#version 450 compatibility





layout(local_size_x = DEF_LocalSize, local_size_y = DEF_LocalSize, local_size_z = 1) in;


layout( binding = 0 ) uniform Buf_LoalParameter0 {
    ivec4 m_Box;
    ivec2 m_Offset;
    uint m_PointNum;
    uint m_IntersectPointNum;
    uint m_Func;
};
layout(std430, binding = 1) buffer Buf_GlobalParameter1 {
    vec2 m_LinePoint[];
};
layout(std430, binding = 2) buffer Buf_GlobalParameter2 {
    uvec2 m_PointStep[];
};
layout(std430, binding = 3) buffer Buf_GlobalParameter3 {
    uvec2 m_PointRange[];
};



void f_ScanRange(const in uint id){
    
    uint localID = gl_LocalInvocationIndex;

    if(id<m_PointNum){
        uvec2 endID_Num = m_PointStep[id].xy;
        endID_Num.x -= endID_Num.y;
        
        uint maxRangeNum = DEF_LocalSize*DEF_LocalSize;

        for(uint i = 0; ; i += maxRangeNum){
            if (localID+i < endID_Num.y) {
                m_PointRange[endID_Num.x + localID + i].x = id;
            }
            barrier();

            if(i>=endID_Num.y){
                break;
            }
        }
    }
}


void main(){
    /*const uint id = (gl_WorkGroupID.y * gl_NumWorkGroups.x*gl_NumWorkGroups.z) 
                    + (gl_NumWorkGroups.x*gl_WorkGroupID.z) 
                    + gl_WorkGroupID.x;*/
    if(m_Func==1){
        const uint id = (gl_WorkGroupID.y * gl_NumWorkGroups.x) + gl_WorkGroupID.x;
        f_ScanRange(id);
        return;
    }
    
    //const uint id = (gl_WorkGroupID.y * gl_NumWorkGroups.x) + gl_WorkGroupID.x;
    const uint id = gl_LocalInvocationIndex;
    uint rangeNum = 0;
    uint endID = id+1;
    if(id < m_PointNum){
        if(endID >= m_PointNum){
            endID = 0;
        }
        rangeNum = uint(abs(round(m_LinePoint[endID+1].y - m_LinePoint[id+1].y)));
        m_PointStep[id].xy = uvec2(rangeNum);
    }
    barrier();

    //-------------------数量偏移计算-----------------------
    for(uint i=1; i<m_PointNum; i*=2){
        if(id+i < m_PointNum){
            m_PointStep[id+i].y += m_PointStep[id].x;
            barrier();
            m_PointStep[id+i].x = m_PointStep[id+i].y;
        }
        barrier();
    }

    
    if (id < m_PointNum) {
        m_PointStep[id].y = rangeNum;
    }
    
}





